<?php

namespace app\logic\provider;

use JetBrains\PhpStorm\ArrayShape;
use Overtrue\Socialite\Contracts;
use Overtrue\Socialite\Exceptions\BadRequestException;
use Overtrue\Socialite\User;

class TwitterProxy extends Twitter
{
    public const NAME = 'twitter_proxy';

    /**
     * 通过授权码获取访问令牌
     *
     * 此方法使用给定的授权码发起请求，以获取访问令牌信息它通过HTTP客户端发送请求，
     * 并对返回的响应进行处理和格式化，以便进一步使用或处理
     *
     * @param string $code 授权码，用于获取访问令牌
     * @return array 格式化后的访问令牌响应数据
     */
    public function tokenFromCode(string $code): array
    {
        $url = config('socialite.proxy.url');
        $data = [
            'url' => $this->getTokenUrl(),
            'method' => 'POST',
            'json' => $this->getTokenFields($code)
        ];
        $response = $this->getHttpClient()->post($url, [
            'headers' => [
                'content-type' => 'application/json',
                'token' => config('socialite.proxy.token')
            ],
            'json' => $data
        ]);
        return $this->normalizeAccessTokenResponse($response->getBody());
    }

    public function userFromCode($code): Contracts\UserInterface
    {
        $tokenResponse = $this->tokenFromCode($code);
        $user = $this->userFromToken($tokenResponse[$this->accessTokenKey]);

        return $user->setRefreshToken($tokenResponse[$this->refreshTokenKey] ?? null)
            ->setExpiresIn($tokenResponse[$this->expiresInKey] ?? null)
            ->setTokenResponse($tokenResponse);
    }


    public function userFromToken(string $token): Contracts\UserInterface
    {
        $user = $this->getUserByToken($token);

        return $this->mapUserToObject($user)->setProvider($this)->setRaw($user)->setAccessToken($token);
    }

    /**
     * 根据给定的认证令牌获取用户信息
     *
     * 本函数通过发送HTTP GET请求到指定的API端点，来获取与给定令牌相关联的用户信息
     * 它首先构造了一个HTTP客户端，然后设置了请求头部，包括内容类型和授权令牌，
     * 最后发送请求并解析响应体为PHP数组格式，返回用户信息
     *
     * @param string $token 用户的认证令牌，用于向API表明用户的身份
     *
     * @return array 包含用户信息的数组，具体结构取决于API的响应
     * @throws BadRequestException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    protected function getUserByToken(string $token): array
    {
        $url = config('socialite.proxy.url');
        $data = [
            'url' => 'https://api.x.com/2/users/me',
            'method' => 'GET',
            'headers' => [
                'content-type' => 'application/json',
                'Authorization' => 'Bearer '.$token,
            ],
            'json' => []
        ];
        $responseInstance = $this->getHttpClient()->post($url, [
            'headers' => [
                'content-type' => 'application/json',
                'token' => config('socialite.proxy.token')
            ],
            'json' => $data
        ]);

        $response = $this->fromJsonBody($responseInstance);

        if (!empty($response['errors'])) {
            throw new BadRequestException((string) $responseInstance->getBody());
        }

        return $response['data'];
    }

}